﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Web.UI.WebControls;
using NetDon.OA.Data;
using NetDon.OA.Data.DaoClasses;
using NetDon.OA.Data.EntityClasses;
using NetDon.OA.Data.HelperClasses;
using NetDon.OA.Data.RelationClasses;
using NetDon.OA.Interface;
using NetDon.OA.Interface.eLogistics;
using SD.LLBLGen.Pro.ORMSupportClasses;

namespace NetDon.OA.Business
{
    public partial class RevenueMachineAccountService : IRevenueMachineAccountService
    {

        public DataTable SearchRevenueMachineAccountDataByConditionForReport(RevenueMachineAccountSearchCriteria criteria, string sortExpression, System.Web.UI.WebControls.SortDirection sortDirection, int pageSize, int pageIndex)
        {

            var fields = new EntityFields(21);
            var index = 0;

            //0
            fields[index++] = new EntityField("Revenues", new ScalarQueryExpression(new EntityField("TotalDeliveryRevenue",
                                              new Expression(
                                                   IssuingOrderDeliveryFields.ConvertedOrderVolumnWeight,
                                                  ExOp.Mul, IssuingOrderDeliveryFields.RevenueUnitCost), AggregateFunction.Sum),
                                                                  IssuingOrderFields.Id ==
                                                                  IssuingOrderDeliveryFields.IssuingOrderId & IssuingOrderFields.Id == RevenueMachineAccountFields.IssuingOrderId, new RelationCollection(IssuingOrderEntity.Relations.IssuingOrderDeliveryEntityUsingIssuingOrderId)));


            //1
            fields[index++] = new EntityField("UnloadingCostWithFactory", new ScalarQueryExpression(new EntityField("TotalUnloadingCostWithFactory",
                                     new Expression(
                                        IssuingOrderDeliveryFields.ConvertedOrderVolumnWeight,
                                         ExOp.Mul, IssuingOrderDeliveryFields.GoodsUnloadingPriceRatio), AggregateFunction.Sum),
                                                         IssuingOrderFields.Id ==
                                                         IssuingOrderDeliveryFields.IssuingOrderId & IssuingOrderFields.Id == RevenueMachineAccountFields.IssuingOrderId, new RelationCollection(IssuingOrderEntity.Relations.IssuingOrderDeliveryEntityUsingIssuingOrderId)));

            //2
            fields[index++] = new EntityField("TotalRevenues", new Expression(new Expression(
           new Expression(new Expression(
         fields[1],
           ExOp.Add, RevenueMachineAccountFields.CarSharingCostWithFactory), ExOp.Add, RevenueMachineAccountFields.OtherRevenue), ExOp.Add, fields[0]), ExOp.Add, RevenueMachineAccountFields.Subsidy));


            //3
            fields[index++] = new EntityField("UnitCost",
                                              new Expression(IssuingOrderFields.ShuntingCost, ExOp.Div, new ScalarQueryExpression(IssuingOrderDeliveryFields.ConvertedOrderVolumnWeight.SetAggregateFunction(AggregateFunction.Sum)
                                                , IssuingOrderFields.Id ==
                                                                  IssuingOrderDeliveryFields.IssuingOrderId, new RelationCollection(IssuingOrderEntity.Relations.IssuingOrderDeliveryEntityUsingIssuingOrderId))));



            //4
            fields[index++] = new EntityField("Cost",
             new Expression(new Expression(IssuingOrderFields.ShuntingCost, ExOp.Add, IssuingOrderFields.GoodsUnloadingCost), ExOp.Add, new ScalarQueryExpression(IssuingOrderVehicleInfoFields.CarSharingPrice.SetAggregateFunction(AggregateFunction.Sum),
                       IssuingOrderFields.Id == IssuingOrderVehicleInfoFields.IssuingOrderId)));
            //5
            fields[index++] = new EntityField("ExtraCost", new Expression(new ScalarQueryExpression(MachineAccountPaymentFields.OtherAmountFromManufactor.SetAggregateFunction(AggregateFunction.Sum), IssuingOrderFields.Id == MachineAccountPaymentFields.IssuingOrderId), ExOp.Sub, new ScalarQueryExpression(MachineAccountPaymentFields.DeductionExceptionsAmount.SetAggregateFunction(AggregateFunction.Sum), IssuingOrderFields.Id == MachineAccountPaymentFields.IssuingOrderId)));

            //6
            fields[index++] = new EntityField("Profit", new Expression(fields[2], ExOp.Sub, new Expression(fields[4], ExOp.Add, fields[5])));

            //7
            fields[index++] = new EntityField("ProfitRate", new Expression(fields[6]) * 100 / new Expression(fields[2]));

            fields[index++] = new EntityField("DeliveryCity", new DbFunctionCall("dbo.GeIssuingOrderCity({0})", new object[] { IssuingOrderFields.Id }));
            fields[index++] = new EntityField("DeliveryAddress", new DbFunctionCall("dbo.GeIssuingOrderAddress({0})", new object[] { IssuingOrderFields.Id }));
            fields[index++] = IssuingOrderFields.OrderVolumn;
            fields[index++] = IssuingOrderFields.OrderWeight;
            fields[index++] = IssuingOrderFields.OrderQuantity;

            fields[index++] = RevenueMachineAccountFields.CarSharingCostWithFactory;
            fields[index++] = RevenueMachineAccountFields.TransportationPlanCode;
            fields[index++] = RevenueMachineAccountFields.OrderCode;
            fields[index++] = new EntityField("CarSharingPrice",
            new ScalarQueryExpression(IssuingOrderVehicleInfoFields.CarSharingPrice.SetAggregateFunction(AggregateFunction.Sum)));

            fields[index++] = RevenueMachineAccountFields.Subsidy;
            fields[index++] = RevenueMachineAccountFields.OtherRevenue;

            fields[index++] = CompanyFields.CompanyName;
            fields[index++] = new EntityField("OrderStatusText", new DbFunctionCall("dbo.GetOrderStatus({0})", new object[] { IssuingOrderFields.OrderStatus }));



            SortExpression expression = new SortExpression
                               {
                                   IssuingOrderFields.ActualShippingDate | SortOperator.Descending
                               };
            expression.Add(IssuingOrderFields.ReceivingOrderDate | SortOperator.Descending);
            expression.Add(RevenueMachineAccountFields.OrderCode | SortOperator.Descending);

            var table = new DataTable("RevenueMachineAccountDS");
            var dao = new TypedListDAO();
            dao.GetMultiAsDataTable(fields, table, 0, expression, GetRevenueMachineAccountPredicate(criteria),
                                    GetRevenueMachineAccountSearchRelationsForReport(), false, null, null, pageIndex + 1, pageSize);


            return table;
        }



        public DataTable SearchRevenueMachineAccountInvoiceByConditionForReport(RevenueMachineAccountInvoiceSearchCriteria criteria, string sortExpression, SortDirection sortDirection, int pageSize, int pageIndex)
        {
            var fields = new EntityFields(13);
            var index = 0;



            fields[index++] = RevenueMachineAccountInvoiceFields.Id;

            fields[index++] = new EntityField("TotalCost", new DbFunctionCall("dbo.GetRevenueMachineAccountTotalCost({0})", new object[] { RevenueMachineAccountInvoiceFields.Id }));



            fields[index++] = CustomerInfoFields.CustomerName;
            fields[index++] = RevenueMachineAccountInvoiceFields.ExpenseDescription;
            fields[index++] = RevenueMachineAccountInvoiceFields.ConfirmInvoiceDate;
            fields[index++] = RevenueMachineAccountInvoiceFields.InvoiceNo;
            fields[index++] = DictionaryFields.Name.SetFieldAlias("InvoiceTypeText");
            fields[index++] = RevenueMachineAccountInvoiceFields.AccountsReceivableDate;

            fields[index++] = RevenueMachineAccountInvoiceFields.StateofAccountAmount;
            fields[index++] = RevenueMachineAccountInvoiceFields.InvoiceAmount;


            fields[index++] = RevenueMachineAccountInvoiceFields.TotalAccountReceiptAmount;
            fields[index++] = new EntityField("UnReceivedAmount", RevenueMachineAccountInvoiceFields.TotalAccountReceiptAmount - RevenueMachineAccountInvoiceFields.InvoiceAmount);
 


            fields[index++] = CompanyFields.CompanyName;
            SortExpression expression = new SortExpression(RevenueMachineAccountInvoiceFields.ConfirmInvoiceDate | SortOperator.Descending);
            expression.Add(RevenueMachineAccountInvoiceFields.InvoiceNo | SortOperator.Ascending);


            var table = new DataTable();
            var dao = new TypedListDAO();
            dao.GetMultiAsDataTable(fields, table, 0, expression, GetRevenueMachineAccountInvoicePredicate(criteria),
                                    GetRevenueMachineAccountInvoiceSearchRelationsForReport(), false, null, null, pageIndex + 1, pageSize);


            return table;
        }

        public DataTable SearchRevenueMachineAccountProfitByConditionForReport(RevenueMachineAccountSearchCriteria criteria, string sortExpression, SortDirection sortDirection, int pageSize, int pageIndex)
        {

            var fields = new EntityFields(12);
            var index = 0;

            //0
            fields[index++] = new EntityField("Revenues", new ScalarQueryExpression(new EntityField("TotalDeliveryRevenue",
                                              new Expression(
                                                   IssuingOrderDeliveryFields.ConvertedOrderVolumnWeight,
                                                  ExOp.Mul, IssuingOrderDeliveryFields.RevenueUnitCost), AggregateFunction.Sum),
                                                                  IssuingOrderFields.Id ==
                                                                  IssuingOrderDeliveryFields.IssuingOrderId & IssuingOrderFields.Id == RevenueMachineAccountFields.IssuingOrderId, new RelationCollection(IssuingOrderEntity.Relations.IssuingOrderDeliveryEntityUsingIssuingOrderId)));


            //1
            fields[index++] = new EntityField("UnloadingCostWithFactory", new ScalarQueryExpression(new EntityField("TotalUnloadingCostWithFactory",
                                     new Expression(
                                        IssuingOrderDeliveryFields.ConvertedOrderVolumnWeight,
                                         ExOp.Mul, IssuingOrderDeliveryFields.GoodsUnloadingPriceRatio), AggregateFunction.Sum),
                                                         IssuingOrderFields.Id ==
                                                         IssuingOrderDeliveryFields.IssuingOrderId & IssuingOrderFields.Id == RevenueMachineAccountFields.IssuingOrderId, new RelationCollection(IssuingOrderEntity.Relations.IssuingOrderDeliveryEntityUsingIssuingOrderId)));

            //2
            fields[index++] = new EntityField("TotalRevenues", new Expression(new Expression(
           new Expression(new Expression(
         fields[1],
           ExOp.Add, RevenueMachineAccountFields.CarSharingCostWithFactory), ExOp.Add, RevenueMachineAccountFields.OtherRevenue), ExOp.Add, fields[0]), ExOp.Add, RevenueMachineAccountFields.Subsidy));





            //3
            fields[index++] = new EntityField("Cost",
             new Expression(new Expression(IssuingOrderFields.ShuntingCost, ExOp.Add, IssuingOrderFields.GoodsUnloadingCost), ExOp.Add, new ScalarQueryExpression(IssuingOrderVehicleInfoFields.CarSharingPrice.SetAggregateFunction(AggregateFunction.Sum),
                       IssuingOrderFields.Id == IssuingOrderVehicleInfoFields.IssuingOrderId)));
            //4
            fields[index++] = new EntityField("ExtraCost", new Expression(new ScalarQueryExpression(MachineAccountPaymentFields.OtherAmountFromManufactor.SetAggregateFunction(AggregateFunction.Sum), IssuingOrderFields.Id == MachineAccountPaymentFields.IssuingOrderId), ExOp.Sub, new ScalarQueryExpression(MachineAccountPaymentFields.DeductionExceptionsAmount.SetAggregateFunction(AggregateFunction.Sum), IssuingOrderFields.Id == MachineAccountPaymentFields.IssuingOrderId)));

            //5
            fields[index++] = new EntityField("Profit", new Expression(fields[2], ExOp.Sub, new Expression(fields[3], ExOp.Add, fields[4])));

            //6
            fields[index++] = new EntityField("ProfitRate", new Expression(fields[5]) * 100 / new Expression(fields[2]));


            fields[index++] = CompanyFields.CompanyName;
            fields[index++] = new EntityField("OrderStatusText", new DbFunctionCall("dbo.GetOrderStatus({0})", new object[] { IssuingOrderFields.OrderStatus }));
            fields[index++] = new EntityField("RouteTypeIdText", new DbFunctionCall("dbo.GeDataDictionary({0})", new object[] { IssuingOrderFields.RouteTypeId }));
            fields[index++] = IssuingOrderFields.ReceivingOrderDate;
            fields[index++] = IssuingOrderFields.OrderCode;
    
            SortExpression expression = new SortExpression
                               {
                                   IssuingOrderFields.ReceivingOrderDate | SortOperator.Descending
                               };
            expression.Add(RevenueMachineAccountFields.OrderCode | SortOperator.Descending);

            var table = new DataTable("RevenueMachineAccountDS");
            var dao = new TypedListDAO();
            dao.GetMultiAsDataTable(fields, table, 0, expression, GetRevenueMachineAccountPredicate(criteria),
                                    GetRevenueMachineAccountSearchRelationsForReport(), false, null, null, pageIndex + 1, pageSize);


            return table;
        }
        private IRelationCollection GetRevenueMachineAccountInvoiceSearchRelationsForReport()
        {
            var relation = new RelationCollection(RevenueMachineAccountInvoiceEntity.Relations.RevenueMachineAccountInvoiceOrderEntityUsingRevenueMachineAccountInvoiceId);

            relation.Add(new DynamicRelation(EntityType.RevenueMachineAccountInvoiceEntity, JoinHint.Left,
                                             EntityType.CompanyEntity, string.Empty, string.Empty,
                                             CompanyFields.CompanyId == RevenueMachineAccountInvoiceFields.AreaId));
            relation.Add(new DynamicRelation(EntityType.RevenueMachineAccountInvoiceEntity, JoinHint.Left,
                                            EntityType.CustomerInfoEntity, string.Empty, string.Empty,
                                            CustomerInfoFields.CustomerId == RevenueMachineAccountInvoiceFields.CustomerId));

            relation.Add(new DynamicRelation(EntityType.RevenueMachineAccountInvoiceEntity, JoinHint.Left,
                                        EntityType.DictionaryEntity, string.Empty, string.Empty,
                                        DictionaryFields.Oid == RevenueMachineAccountInvoiceFields.InvoiceType));

            return relation;
        }

        private IRelationCollection GetRevenueMachineAccountSearchRelationsForReport()
        {
            var relation = new RelationCollection(RevenueMachineAccountEntity.Relations.IssuingOrderEntityUsingIssuingOrderId, JoinHint.Left);

            relation.Add(new DynamicRelation(EntityType.RevenueMachineAccountEntity, JoinHint.Left,
                                             EntityType.CompanyEntity, string.Empty, string.Empty,
                                             CompanyFields.CompanyId == RevenueMachineAccountFields.AreaId));

            return relation;
        }

    }
}
